#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <crypto/hash.h>
#include <crypto/public_key.h>
#include <linux/err.h>
#include <linux/kernel_read_file.h>
#include "x509_parser.h"

#define CLIENT_CERT_PATH "/home/lighthouse/parse_x509_ko/ecdsa_server.crt"

static int __init x509_parser_init(void)
{
    pr_info("Loading X.509 parser module\n");
    void *data;
    int certlen, ret;
    struct x509_certificate *cert;
    data = kzalloc(1024 * sizeof(int), GFP_KERNEL);
    certlen = kernel_read_file_from_path(CLIENT_CERT_PATH, 0, &data, INT_MAX, NULL,
                                         READING_X509_CERTIFICATE);
    if (certlen < 0) {
        pr_info("read file failed \n");
    } else {
        pr_info("certlen:%d\n", certlen);
    }

    cert = x509_cert_parse(data, certlen);
    print_hex_dump(KERN_CONT, "cert:", DUMP_PREFIX_OFFSET, 16, 1, data, certlen, false);

    if (IS_ERR(cert)) {
        ret = PTR_ERR(cert);
        pr_err("Failed to parse certificate: %d\n", ret);
        kfree(data);
        return ret;
    }

    pr_info("Certificate parsed successfully\n");
    pr_info("Issuer: %s\n", cert->issuer);
    pr_info("Subject: %s\n", cert->subject);
    ret = public_key_verify_signature(cert->pub, cert->sig);

    if (ret < 0) {
        pr_info("verify failed!\n");
    } else {
        pr_info("verify success!\n");
    }
    return 0;
}

static void __exit x509_parser_exit(void)
{
    pr_info("Unloading X.509 parser module\n");
}

module_init(x509_parser_init);
module_exit(x509_parser_exit);

MODULE_LICENSE("GPL");
